﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Inovout.Web.Mvc
{
    public class WidgetCollectionModelMetadata : WidgetModelMetadata
    {
        #region 构造器
        public WidgetCollectionModelMetadata(CachedDataAnnotationsModelMetadataProvider provider, Type containerType, Type modelType, string propertyName, IEnumerable<Attribute> attributes)
            : base(provider, containerType, modelType, propertyName, new CachedWidgetMetadataAttributes(attributes))
        {
            PrototypeCache = new CachedWidgetMetadataAttributes(attributes);
        }

        public WidgetCollectionModelMetadata(CachedDataAnnotationsModelMetadata prototype, Func<object> modelAccessor)
            : base(prototype, modelAccessor)
        {
            ModelDeclaringType = prototype.ModelType;
        }
        #endregion

        private WidgetModelMetadata widgetElementModelMetadata;
        public WidgetModelMetadata WidgetElementModelMetadata
        {
            get
            {
                if (widgetElementModelMetadata == null)
                {
                    Type modelTypeInGeneric = base.ModelType.IsArray ? base.ModelType.GetElementType() : base.ModelType.GetGenericArguments().First();
                    widgetElementModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, modelTypeInGeneric).AsWidgetModelMetadata();

                    Type modelDeclaringTypeInGeneric = base.ModelDeclaringType.IsArray?base.ModelDeclaringType.GetElementType(): base.ModelDeclaringType.GetGenericArguments().First();
                    widgetElementModelMetadata.ModelDeclaringType = modelDeclaringTypeInGeneric;
                }
                return widgetElementModelMetadata;
            }
            internal set { widgetElementModelMetadata = value; }
        }
        internal void EmptyCollectionRender(Func<object> emptyCollectionRender)
        {
            base.NullDisplayText = emptyCollectionRender().ToString();
        }
        internal override void Merge(WidgetModelMetadata widgetModelMetadata)
        {
            if (widgetModelMetadata is WidgetCollectionModelMetadata)
            {
                Type typeInGeneric = null;
                if (base.ModelDeclaringType.IsGenericType)
                {
                    typeInGeneric = base.ModelDeclaringType.GetGenericArguments().First();
                }
                var metadata = widgetModelMetadata.AsWidgetCollectionModelMetadata();
                if (metadata.widgetElementModelMetadata != null && typeInGeneric != null && typeInGeneric.Equals(metadata.widgetElementModelMetadata.ModelDeclaringType))
                {
                    this.widgetElementModelMetadata = metadata.widgetElementModelMetadata;
                }
            }
        }
    }
}
